﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Data.SqlClient;
using Estimate.Common;
using Estimate.Common.DBFieldTypes;
using Estimate.Common.Entity;
using Estimate.Common.Repository;

namespace Estimate.OldSemiCompare.Transfer
{
    public abstract class BaseForeTransfer : ITranferTableData
    {
        protected string _oldConnectionString;
        protected string _newConnectionString;

        protected ForeRepository Repository;
        

        public BaseForeTransfer(string oldConnectionString, string newConnectionString) 
        {
            _oldConnectionString = oldConnectionString;
            _newConnectionString = newConnectionString;
        }

        public void WriteLog(string e)
        {
            Console.WriteLine(e);
        }

        public virtual string GetTableName()
        {
            return "BaseFore";
        }

        public void TransformData(string table)
        {
            Repository = this.getRepository(table);
            if (!Repository.IsTableExist())
            {
                Repository.CreateTable();
            }

            string sql = string.Format("SELECT * FROM [{0}]", table);

            SqlConnection connection = new SqlConnection(_oldConnectionString);
            SqlDataReader reader =  DBHelper.ExecuteReader(connection, sql);
            ForeEntity entity_manual = null;
            ForeEntity entity_auto = null;
            while (reader.Read())
            {
                try{
                    
                    string value = reader["value"].ToString();
                    if (value.Trim() == "")
                    {//空值数据去除
                        continue;
                    }
                    string semi = reader["semi"].ToString();
                    if (semi.Length > 0)
                    {
                        if (semi[semi.Length - 1] == '|')
                        {
                            semi = semi.Substring(0, semi.Length - 1);
                        }
                    }

                    int year = Convert.ToInt32((reader["date"].ToString().Substring(0,4)));
                    int month = Convert.ToInt32((reader["date"].ToString().Substring(4,2)));
                    int day = Convert.ToInt32((reader["date"].ToString().Substring(6,2)));
                    DateTime date = new DateTime( year,month,day);
                    ForeClockType clock = (ForeClockType)Enum.Parse(typeof(ForeClockType), "H" + ((string)reader["clock"]).Trim());

                    ForeSendpointType sendpoint = ForeSendpointType.H06;
                    if (clock == ForeClockType.H08)
                    {
                        sendpoint = ForeSendpointType.H06;
                    }
                    else
                    {
                        sendpoint = ForeSendpointType.H16;
                    }

                    int intSpan = Convert.ToInt32(((string)reader["span"]).Trim());
                    ForeSpanType span = getSpanByInt(intSpan);
                    
                    ForeFactorType type = ForeFactorType.maxt;
                    string strType = ((string)reader["type"]).Trim();
                    switch (strType)
                    {
                        case "wth1":
                            type = ForeFactorType.wth;
                            span = getSpan(1, span);
                            break;
                        case "wth2":
                            type = ForeFactorType.wth;
                            span = getSpan(2, span);
                            break;
                        case "ws1":
                            type = ForeFactorType.ws;
                            span = getSpan(1, span);
                            break;
                        case "ws2":
                            type = ForeFactorType.ws;
                            span = getSpan(2, span);
                            break;
                        case "wd1":
                            type = ForeFactorType.wd;
                            span = getSpan(1, span);
                            break;
                        case "wd2":
                            type = ForeFactorType.wd;
                            span = getSpan(2, span);
                            break;
                        case "mint":
                            type = ForeFactorType.mint;
                            break;
                        case "maxt":
                            type = ForeFactorType.maxt;
                            break;
                        case "wth":
                            type = ForeFactorType.wth;                            
                            break;
                    }
                    
                    ForeSemiType semitype = ForeSemiType.Manual;

                    entity_manual = new ForeEntity(date,clock,span,type,semitype,sendpoint,value);
                    entity_manual.Semi = semi;

                    semitype = ForeSemiType.Auto;
                    entity_auto = new ForeEntity(date, clock, span, type, semitype, sendpoint, value);
                    entity_auto.Semi = semi;
                }
                catch(Exception e)
                {
                    this.WriteLog("\n");
                    this.WriteLog(string.Format("{0}: \n \t id:{1}, \n\t message:{2}", table, reader["id"], e.Message));
                    this.WriteLog("\n");
                    this.WriteLog(string.Format("\t\t date={0}\t, clock={1}, span={2}, type={3}", reader["date"].ToString(), reader["clock"].ToString(), reader["span"].ToString(),reader["type"].ToString()));
                    this.WriteLog(string.Format("\t\t value={0}\t, semi={1}", reader["value"].ToString(), reader["semi"].ToString()));
                    continue;
                }
                this.SaveData(entity_manual);
                this.SaveData(entity_auto);
            }
            connection.Close();

        }

        /// <summary>
        /// 给定前半段 1 或者后半段 2， 并给定24小时的区间，则生成12小时的区间
        /// </summary>
        /// <param name="number"></param>
        /// <param name="fullSpan"></param>
        /// <returns></returns>
        private ForeSpanType getSpan(int number, ForeSpanType fullSpan)
        {
            ForeSpanType result = ForeSpanType.FD00_12;
            switch (fullSpan)
            {
                case ForeSpanType.FD00_24:
                    result = number == 1 ? ForeSpanType.FD00_12 : ForeSpanType.FD12_24;
                    break;
                case ForeSpanType.FD24_48:
                    result = number == 1 ? ForeSpanType.FD24_36 : ForeSpanType.FD36_48;
                    break;
                case ForeSpanType.FD48_72:
                    result = number == 1 ? ForeSpanType.FD48_60 : ForeSpanType.FD60_72;
                    break;
                case ForeSpanType.FD72_96:
                    result = number == 1 ? ForeSpanType.FD72_84 : ForeSpanType.FD84_96;
                    break;
                case ForeSpanType.FD96_120:
                    result = number == 1 ? ForeSpanType.FD96_108 : ForeSpanType.FD108_120;
                    break;
                case ForeSpanType.FD120_144:
                    result = number == 1 ? ForeSpanType.FD120_132 : ForeSpanType.FD132_144;
                    break;
            }
            return result;
        }

        /// <summary>
        /// 根据给定的数字获取时间段
        /// </summary>
        /// <param name="span"></param>
        /// <returns></returns>
        private ForeSpanType getSpanByInt(int span)
        {
            ForeSpanType result = ForeSpanType.FD00_24;
            switch (span)
            {
                case 24:
                    result = ForeSpanType.FD00_24;
                    break;
                case 48:
                    result = ForeSpanType.FD24_48;
                    break;
                case 72:
                    result = ForeSpanType.FD48_72;
                    break;
                case 96:
                    result = ForeSpanType.FD72_96;
                    break;
                case 120:
                    result = ForeSpanType.FD96_120;
                    break;
                case 144:
                    result = ForeSpanType.FD120_144;
                    break;
                case 168:
                    result = ForeSpanType.FD144_168;
                    break;
            }
            return result;
        }

        protected virtual void SaveData(ForeEntity entity)
        {
            Repository.SetForeRecord(entity);
        }
        protected abstract ForeRepository getRepository(string table);
        
    }
}
